#include "FOV.h"
#include "../SGD Wrappers/SGD_Geometry.h"
#include "../SGD Wrappers/SGD_AudioManager.h"
#include "EnemyUnit.h"
#include "SecurityCamera.h"
#include "Player.h"
#include "../SGD Wrappers/SGD_Event.h"
#include "GameplayState.h"


FOV::FOV()
{
	aware = &GameplayState::GetInstance()->aware;

}

FOV::~FOV()
{
	
	/*for (unsigned int currRect = 0; currRect < Collidables.size(); currRect++)
	{
		if (Collidables[currRect] != nullptr)
		{
			Collidables[currRect] = nullptr;
		}
		

	}*/
	Collidables.clear();

}
void FOV::Update(float dt)
{	
	/*m_ptPosition = m_pOwner->GetPosition();
	m_fRotation = m_pOwner->GetRotation();*/

	if (lookForPlayer() == true)
	{
		if (m_pOwner->GetAIState() != EnemyUnit::AIStates::ALERT)
		{
			SGD::AudioManager::GetInstance()->PlayAudio(*aware);
			SGD::Event* lostTarget = new SGD::Event("TARGET_FOUND");
			lostTarget->QueueEvent((EnemyUnit*)m_pOwner);
			lostTarget = nullptr;

		}
	}
	else
	{
		if (m_pOwner->GetAIState() == EnemyUnit::AIStates::ALERT)
		{
			SGD::Event* lostTarget = new SGD::Event("LOST_TARGET");
			lostTarget->QueueEvent((EnemyUnit*)m_pOwner);
			lostTarget = nullptr;

		}	
	}
}
void FOV::Render()
{
	
}

bool FOV::lookForPlayer()
{
	if (hasLOS(m_pOwner->GetPosition(), m_pOwner->GetTarget()->GetPosition()))
	{
		
		SGD::Vector toPlayer = m_pOwner->GetTarget()->GetPosition() - m_pOwner->GetPosition();
		if (toPlayer.ComputeLength() <= m_fViewDistance)
		{
			
			toPlayer.Normalize();
			if (m_pOwner->direction.ComputeAngle(toPlayer) < .35f)
			{
				if (m_pOwner->GetAIState() == m_pOwner->ALERT)
					return true;
				if (m_pOwner->GetType() == BaseObject::OBJ_DOG)
				{
					if (m_pOwner->GetTarget()->GetVisibleState() == Player::VISIBLE
						|| m_pOwner->GetTarget()->GetVisibleState() == Player::SHADOWED)
						return true;
				}
				else
				{
					if (m_pOwner->GetType() == BaseObject::OBJ_CAMERA)
					{
						SecurityCamera* camera = dynamic_cast<SecurityCamera*>(m_pOwner);

						if (camera->IsThermal())
							return true;
						else if (m_pOwner->GetTarget()->GetVisibleState() == Player::VISIBLE)
							return true;
					}
					else
					{
						if (m_pOwner->GetTarget()->GetVisibleState() == Player::VISIBLE)
							return true;
					}
						
				}
			}
		}
	}
	return false;
}

bool FOV::hasLOS(SGD::Point startPos, SGD::Point endPos)
{
	SGD::Vector perMove = (endPos - startPos);
	perMove.Normalize();
	if (losTimer.Update(Game::GetInstance()->DeltaTime()))
	{
		while (startPos.ComputeDifference(endPos).ComputeLength() > 1 && perMove.ComputeLength() < m_fViewDistance)
		{

			for (unsigned int i = 0; i < Collidables.size(); i++)
			{
				if (startPos.IsWithinRectangle(*Collidables[i]))
					return false;
			}

			startPos += perMove;
		}
		return true;
	}
	else
		losTimer.AddTime(.10f);
	return false;
	
}

void FOV::SetOwner(EnemyUnit* owner)
{
	if (m_pOwner != nullptr)
	{
		m_pOwner->Release();
		m_pOwner = nullptr;
	}
	m_pOwner = owner;
}

void FOV::PopulateCollidables(std::vector<SGD::Rectangle*>& collidables)
{
	for (unsigned int i = 0; i < collidables.size(); i++)
	{
		Collidables.push_back(collidables[i]);
	}
}
